package com.qingcheng.task;


import com.qingcheng.dao.SeckillGoodsMapper;
import com.qingcheng.pojo.seckill.SeckillGoods;
import com.qingcheng.pojo.seckill.SeckillOrder;
import com.qingcheng.util.IdWorker;
import com.qingcheng.util.SeckillStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Date;


/**
 * 抢单程序
 *
 * 多线程异步操作类
 */
@Component
public class MultiThreadingCreateOrder {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private IdWorker idWorker;
    /**
     * 多线程下单操作
     */
    @Async
    public void createOrder(){




        try {
            System.out.println("准备执行...");
            Thread.sleep(10000);

            SeckillStatus seckillstatus = (SeckillStatus)redisTemplate.boundListOps("SeckillOrderQueue").rightPop();



            //用户抢单数据
     String username =seckillstatus.getUsername();
     String time = seckillstatus.getTime();
            Long id= seckillstatus.getGoodsId();


            //获取队列中的商品Id
            Object sid = redisTemplate.boundListOps("SeckillGoodsCountList_" + id).rightPop();

            //判断如果售罄
            if(sid==null){
                //清理排队信息
                clearQueue(seckillstatus);
                return;
            }



            //查询商品详情
            SeckillGoods goods = (SeckillGoods) redisTemplate.boundHashOps("SeckillGoods_"+time).get(id);

            Thread.sleep(10000);
            System.out.println(username+":"+Thread.currentThread().getId() + "--------查询到的商品库存:" + goods.getStockCount());



            if(goods!=null && goods.getStockCount()>0){
                //创建订单
                SeckillOrder seckillOrder = new SeckillOrder();
                seckillOrder.setId(idWorker.nextId());
                seckillOrder.setSeckillId(id);
                seckillOrder.setMoney(goods.getCostPrice());
                seckillOrder.setUserId(username);
                seckillOrder.setSellerId(goods.getSellerId());
                seckillOrder.setCreateTime(new Date());
                seckillOrder.setStatus("0");
                //将秒杀订单存入到Redis中
                redisTemplate.boundHashOps("SeckillOrder").put(username,seckillOrder);

                //控制数据精准的解决方案
                Long surplusCount = redisTemplate.boundHashOps("SeckillGoodsCount").increment(goods.getId(), -1);

                //库存削减
                goods.setStockCount(surplusCount.intValue());
                //商品库存=0->将数据同步到MySQL，并清理Redis缓存
                if(surplusCount<=0){
                    seckillGoodsMapper.updateByPrimaryKeySelective(goods);
                    //清理Redis缓存
                    redisTemplate.boundHashOps("SeckillGoods_"+time).delete(id);
                }else{
                    //将数据同步到Redis
                    redisTemplate.boundHashOps("SeckillGoods_"+time).put(id,goods);
                }

             //变更抢单状态
                seckillstatus.setOrderId(seckillOrder.getId());
                seckillstatus.setMoney(seckillOrder.getMoney().floatValue());
                seckillstatus.setStatus(2);//抢单成功，待支付
                //将抢单状态存入到Redis中
                redisTemplate.boundHashOps("UserQueueStatus").put(username,seckillstatus);
            }




            System.out.println("开始执行...");

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 清理用户排队信息
     * @param seckillstatus
     */
    private void clearQueue(SeckillStatus seckillstatus) {

        //清理重复排队标识
        redisTemplate.boundHashOps("UserQueueCount").delete(seckillstatus.getUsername());

        //清理排队存储信息
        redisTemplate.boundHashOps("UserQueueStatus").delete(seckillstatus.getUsername());

    }
}
